import { Injectable } from '@nestjs/common';
import { fsStat, streamMd5 } from '../utils/fs';
import * as path from 'path';
import { FileInfo } from '../entities/FileInfo';
import { FileStorage } from '../entities/FileStorage';
import * as fse from 'fs-extra';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

@Injectable()
export class VideoService {
    constructor(
        @InjectRepository(FileStorage)
        private readonly fileStorage: Repository<FileStorage>,
        @InjectRepository(FileInfo)
        private readonly fileInfo: Repository<FileInfo>,
    ) {
    }

    async moveMd5Other(filepath: string, md5: string, md5path: string, ext: string) {
        try {
            const target = filepath.replace(/\.mp4$/, ext);
            const fss = await fsStat(target);
            if (fss.isFile()) {
                await fse.copyFile(
                    target,
                    path.resolve(
                        md5path,
                        md5 + ext,
                    ),
                );
                await fse.unlink(target);
            }
        } catch (e) {
        }
    }

    async action(filepath: string, targetpath: string) {
        const fss = await fsStat(filepath);
        if (fss.isFile() && path.extname(filepath).toLowerCase() === '.mp4') {
            const md5 = await streamMd5(filepath);
            const md5path = path.resolve(
                targetpath,
                md5.substring(0, 4),
                md5.substring(4, 8),
            );
            const fileStorage = await this.fileStorage.findOne({md5});
            if (!fileStorage) {
                const fileInfo = new FileInfo();
                const fileStorage = new FileStorage();
                fileInfo.name = path.basename(filepath);
                fileInfo.extname = 'mp4';
                fileStorage.md5 = md5;
                fileStorage.extname = 'mp4';
                fileStorage.fileCreateTime = fss.birthtime;
                fileStorage.fileModifyTime = fss.mtime;
                fileStorage.size = fss.size;
                fileStorage.filepath = path.resolve(
                    md5path,
                    md5 + '.mp4',
                );
                fileInfo.fileStorage = fileStorage;
                await fse.ensureDir(md5path, {});
                await fse.copyFile(filepath, fileStorage.filepath);
                await this.fileInfo.save(fileInfo);
                await fse.unlink(filepath);
                await this.moveMd5Other(filepath, md5, md5path, '.ass');
                await this.moveMd5Other(filepath, md5, md5path, '.jpg');
                await this.moveMd5Other(filepath, md5, md5path, '.png');
                return {
                    message: '已成功',
                };
            } else if (fileStorage.isDeleted) {
                await fse.unlink(filepath);
                await this.moveMd5Other(filepath, md5, md5path, '.ass');
                await this.moveMd5Other(filepath, md5, md5path, '.jpg');
                await this.moveMd5Other(filepath, md5, md5path, '.png');
                return {
                    message: 'md5对应的视频已经被删除,不是我的菜',
                };
            } else {
                await fse.unlink(filepath);
                await this.moveMd5Other(filepath, md5, md5path, '.ass');
                await this.moveMd5Other(filepath, md5, md5path, '.jpg');
                await this.moveMd5Other(filepath, md5, md5path, '.png');
                return {
                    message: 'md5已存在',
                };
            }
        } else {
            return {
                message: '不是文件，不是mp4',
            };
        }
    }
}
